namespace NUnitTests{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Guia.Core;
    using Guia.Elements;
    using NUnit.Framework;
    using WpfTestApplication;

    /// <summary>
    /// Summary description for CalendarTest
    /// </summary>
    [TestFixture]
    public class CalendarTest : AbstractWindowTest
    {
        [Test]
        public void TestView()
        {
            Calendar calendar1 = this.window.Get<Calendar>("calendar1");
            Assert.AreEqual(Calendar.ECalendarView.MONTH, calendar1.View);
            calendar1.View = Calendar.ECalendarView.YEAR;
            Assert.AreEqual(Calendar.ECalendarView.YEAR, calendar1.View);
            calendar1.View = Calendar.ECalendarView.DECADE;
            Assert.AreEqual(Calendar.ECalendarView.DECADE, calendar1.View);
            calendar1.View = Calendar.ECalendarView.MONTH;
            Assert.AreEqual(Calendar.ECalendarView.MONTH, calendar1.View);
        }

        [Test]
        public void TestNext()
        {
            Calendar calendar1 = this.window.Get<Calendar>("calendar1");
            calendar1.Next();
        }

        [Test]
        public void TestPrevious()
        {
            Calendar calendar1 = this.window.Get<Calendar>("calendar1");
            calendar1.Previous();
        }

        [Test]
        public void TestSetSelectedDate()
        {
            Calendar calendar1 = this.window.Get<Calendar>("calendar1");
            DateTime dateTime = DateTime.Today.AddYears(1);
            calendar1.SetSelectedDate(dateTime);
            DateTime[] selectedDates = calendar1.SelectedDates;
            Assert.AreEqual(1, selectedDates.Length);
            Assert.AreEqual(dateTime, selectedDates[0]);
        }

        [Test,ExpectedException(typeof(OperationNotSupportedException))]
        public void TestSetSelectedDateDisabled()
        {
            Calendar calendar5 = this.window.Get<Calendar>("calendar5");
            DateTime dateTime = DateTime.Today.AddYears(1);
            calendar5.SetSelectedDate(dateTime);
        }

        [Test]
        public void TestSetSelectedDateInPast()
        {
            Calendar calendar1 = this.window.Get<Calendar>("calendar1");
            DateTime dateTime = DateTime.Parse("31.12.2009");
            calendar1.SetSelectedDate(dateTime);
            DateTime[] selectedDates = calendar1.SelectedDates;
            Assert.AreEqual(1, selectedDates.Length);
            Assert.AreEqual(dateTime, selectedDates[0]);
        }

        [Test]
        public void TestAddDateToSelection()
        {
            Calendar calendar3 = this.window.Get<Calendar>("calendar3");
            DateTime dateTime1 = DateTime.Today.AddYears(1);
            calendar3.SetSelectedDate(dateTime1);
            DateTime dateTime2 = dateTime1.AddDays(1);
            calendar3.AddDateToSelection(dateTime2);
            DateTime[] selectedDates = calendar3.SelectedDates;
            Assert.AreEqual(2, selectedDates.Length);
            Assert.AreEqual(dateTime1, selectedDates[0]);
            Assert.AreEqual(dateTime2, selectedDates[1]);
        }

        [Test, ExpectedException(typeof(OperationNotSupportedException))]
        public void TestAddDateToSelectionDisabled()
        {
            Calendar calendar5 = this.window.Get<Calendar>("calendar5");
            DateTime dateTime = DateTime.Today.AddYears(1);
            calendar5.AddDateToSelection(dateTime);
        }

        [Test]
        public void TestUnselectDate()
        {
            Calendar calendar3 = this.window.Get<Calendar>("calendar3");
            DateTime dateTime1 = DateTime.Today.AddYears(1);
            calendar3.SetSelectedDate(dateTime1);
            DateTime dateTime2 = dateTime1.AddDays(1);
            calendar3.AddDateToSelection(dateTime2);
            DateTime[] selectedDates = calendar3.SelectedDates;
            Assert.AreEqual(2, selectedDates.Length);
            Assert.AreEqual(dateTime1, selectedDates[0]);
            Assert.AreEqual(dateTime2, selectedDates[1]);
            calendar3.UnselectDate(dateTime1);
            selectedDates = calendar3.SelectedDates;
            Assert.AreEqual(1, selectedDates.Length);
            Assert.AreEqual(dateTime2, selectedDates[0]);
        }

        [Test, ExpectedException(typeof(OperationNotSupportedException))]
        public void TestUnselectDateDisabled()
        {
            Calendar calendar5 = this.window.Get<Calendar>("calendar5");
            DateTime dateTime = DateTime.Today.AddYears(1);
            calendar5.UnselectDate(dateTime);
        }

        [Test]
        public void TestSelectRange()
        {
            Calendar calendar3 = this.window.Get<Calendar>("calendar3");
            DateTime dateTimeStart = DateTime.Today.AddYears(1);
            DateTime dateTimeEnd = dateTimeStart.AddDays(5);
            calendar3.SelectRange(dateTimeStart, dateTimeEnd);
            DateTime[] selectedDates = calendar3.SelectedDates;
            Assert.AreEqual(6, selectedDates.Length);
            Assert.AreEqual(dateTimeStart, selectedDates[0]);
            Assert.AreEqual(dateTimeStart.AddDays(1), selectedDates[1]);
            Assert.AreEqual(dateTimeStart.AddDays(2), selectedDates[2]);
            Assert.AreEqual(dateTimeStart.AddDays(3), selectedDates[3]);
            Assert.AreEqual(dateTimeStart.AddDays(4), selectedDates[4]);
            Assert.AreEqual(dateTimeStart.AddDays(5), selectedDates[5]);
            Assert.AreEqual(dateTimeEnd, selectedDates[5]);
        }

        [Test]
        public void TestSelectRangeOneDay()
        {
            Calendar calendar3 = this.window.Get<Calendar>("calendar3");
            DateTime dateTimeStart = DateTime.Today.AddYears(1);
            DateTime dateTimeEnd = dateTimeStart;
            calendar3.SelectRange(dateTimeStart, dateTimeEnd);
            DateTime[] selectedDates = calendar3.SelectedDates;
            Assert.AreEqual(1, selectedDates.Length);
            Assert.AreEqual(dateTimeStart, selectedDates[0]);
            Assert.AreEqual(dateTimeEnd, selectedDates[0]);
        }

        [Test, ExpectedException(typeof(OperationNotSupportedException))]
        public void TestSelectRangeDisabled()
        {
            Calendar calendar5 = this.window.Get<Calendar>("calendar5");
            DateTime dateTimeStart = DateTime.Today.AddYears(1);
            DateTime dateTimeEnd = dateTimeStart.AddDays(5);
            calendar5.SelectRange(dateTimeStart, dateTimeEnd);
        }

        [Test, ExpectedException(typeof(ArgumentException))]
        public void TestSelectRangeIllegalStartEndDates()
        {
            Calendar calendar3 = this.window.Get<Calendar>("calendar3");
            DateTime dateTimeStart = DateTime.Today.AddYears(1);
            DateTime dateTimeEnd = dateTimeStart.AddDays(5);
            calendar3.SelectRange(dateTimeEnd, dateTimeStart);
        }

        [Test]
        public void TestAddRangeToSelection()
        {
            Calendar calendar3 = this.window.Get<Calendar>("calendar3");
            DateTime dateTimeStart1 = DateTime.Today.AddYears(1);
            DateTime dateTimeEnd1 = dateTimeStart1.AddDays(5);
            calendar3.SelectRange(dateTimeStart1, dateTimeEnd1);
            DateTime[] selectedDates1 = calendar3.SelectedDates;

            DateTime dateTimeStart2 = DateTime.Today.AddMonths(1);
            DateTime dateTimeEnd2 = dateTimeStart2.AddDays(2);
            calendar3.AddRangeToSelection(dateTimeStart2, dateTimeEnd2);
            DateTime[] selectedDates2 = calendar3.SelectedDates;

            DateTime[] selectedDates = selectedDates1.Concat(selectedDates2).ToArray();

            Assert.AreEqual(9, selectedDates.Length);
            Assert.AreEqual(dateTimeStart1, selectedDates[0]);
            Assert.AreEqual(dateTimeStart1.AddDays(1), selectedDates[1]);
            Assert.AreEqual(dateTimeStart1.AddDays(2), selectedDates[2]);
            Assert.AreEqual(dateTimeStart1.AddDays(3), selectedDates[3]);
            Assert.AreEqual(dateTimeStart1.AddDays(4), selectedDates[4]);
            Assert.AreEqual(dateTimeStart1.AddDays(5), selectedDates[5]);
            Assert.AreEqual(dateTimeEnd1, selectedDates[5]);
            Assert.AreEqual(dateTimeStart2, selectedDates[6]);
            Assert.AreEqual(dateTimeStart2.AddDays(1), selectedDates[7]);
            Assert.AreEqual(dateTimeStart2.AddDays(2), selectedDates[8]);
            Assert.AreEqual(dateTimeEnd2, selectedDates[8]);
        }

        [Test]
        public void TestAddRangeToSelectionOneDay()
        {
            Calendar calendar3 = this.window.Get<Calendar>("calendar3");
            DateTime dateTimeStart1 = DateTime.Today.AddYears(1);
            DateTime dateTimeEnd1 = dateTimeStart1.AddDays(5);
            calendar3.SelectRange(dateTimeStart1, dateTimeEnd1);
            DateTime[] selectedDates1 = calendar3.SelectedDates;

            DateTime dateTimeStart2 = DateTime.Today.AddMonths(1);
            DateTime dateTimeEnd2 = dateTimeStart2;
            calendar3.AddRangeToSelection(dateTimeStart2, dateTimeEnd2);
            DateTime[] selectedDates2 = calendar3.SelectedDates;

            DateTime[] selectedDates = selectedDates1.Concat(selectedDates2).ToArray();

            Assert.AreEqual(7, selectedDates.Length);
            Assert.AreEqual(dateTimeStart1, selectedDates[0]);
            Assert.AreEqual(dateTimeStart1.AddDays(1), selectedDates[1]);
            Assert.AreEqual(dateTimeStart1.AddDays(2), selectedDates[2]);
            Assert.AreEqual(dateTimeStart1.AddDays(3), selectedDates[3]);
            Assert.AreEqual(dateTimeStart1.AddDays(4), selectedDates[4]);
            Assert.AreEqual(dateTimeStart1.AddDays(5), selectedDates[5]);
            Assert.AreEqual(dateTimeEnd1, selectedDates[5]);
            Assert.AreEqual(dateTimeStart2, selectedDates[6]);
            Assert.AreEqual(dateTimeEnd2, selectedDates[6]);
        }

        [Test, ExpectedException(typeof(OperationNotSupportedException))]
        public void TestAddRangeToSelectionDisabled()
        {
            Calendar calendar5 = this.window.Get<Calendar>("calendar5");
            DateTime dateTimeStart = DateTime.Today.AddYears(1);
            DateTime dateTimeEnd = dateTimeStart.AddDays(5);
            calendar5.AddRangeToSelection(dateTimeStart, dateTimeEnd);
        }

        [Test, ExpectedException(typeof(ArgumentException))]
        public void TestAddRangeToSelectionIllegalStartEndDates()
        {
            Calendar calendar3 = this.window.Get<Calendar>("calendar3");
            DateTime dateTimeStart = DateTime.Today.AddYears(1);
            DateTime dateTimeEnd = dateTimeStart.AddDays(5);
            calendar3.AddRangeToSelection(dateTimeEnd, dateTimeStart);
        }

        [Test]
        public void TestNavigateToMonth()
        {
            Calendar calendar1 = this.window.Get<Calendar>("calendar1");
            calendar1.NavigateToMonth(1, DateTime.Today.Year);
            DateTime shownDate = DateTime.Parse(calendar1.HeaderValue);
            Assert.AreEqual(DateTime.Parse("January " + DateTime.Today.Year), shownDate);
        }

        [Test]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void TestNavigateToInvalidMonth1()
        {
            Calendar calendar1 = this.window.Get<Calendar>("calendar1");
            calendar1.NavigateToMonth(0, DateTime.Today.Year);
        }

        [Test]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void TestNavigateToInvalidMonth2()
        {
            Calendar calendar1 = this.window.Get<Calendar>("calendar1");
            calendar1.NavigateToMonth(13, DateTime.Today.Year);
        }

        [Test, ExpectedException(typeof(OperationNotSupportedException))]
        public void TestNavigateToMonthDisabled()
        {
            Calendar calendar5 = this.window.Get<Calendar>("calendar5");
            calendar5.NavigateToMonth(1, 2010);
        }

        #region Overrides of AbstractWindowTest

        protected override Type TestWindowType()
        {
            return typeof (CalendarTestWindow);
        }

        protected override string TestWindowName()
        {
            return "CalendarTestWindow";
        }

        #endregion
    }
}
